<template>
  <div class="rtsp-hls-container">
    <header class="rtsp-hls-header">
      <h1>多源 RTSP 转 HLS 工具</h1>
    </header>

    <!-- 配置管理区 -->
    <div class="rtsp-hls-config-area">
      <h3>流配置管理</h3>
      <div class="rtsp-hls-config-form">
        <div class="rtsp-hls-form-group">
          <label for="streamId">id</label>
          <input
            id="streamId"
            v-model="newStream.id"
            type="text"
            placeholder="如：1"
            class="rtsp-hls-input"
          />
        </div>
        <div class="rtsp-hls-form-group">
          <label for="streamName">流名称</label>
          <input
            id="streamName"
            v-model="newStream.name"
            type="text"
            placeholder="如：摄像头1"
            class="rtsp-hls-input"
          />
        </div>
        <div class="rtsp-hls-form-group">
          <label for="rtspUrl">RTSP 地址</label>
          <input
            id="rtspUrl"
            v-model="newStream.rtsp"
            type="text"
            placeholder="rtsp://user:pass@ip:port/path"
            class="rtsp-hls-input"
          />
        </div>
        <div style="margin-top: 19px">
          <button class="rtsp-hls-button" @click="addStreamConfig">添加流配置</button>
        </div>
        <!-- <div style="margin-top: 19px">
          <button class="rtsp-hls-button" @click="stopAllStreaming">重置所有转码</button>
        </div> -->
      </div>

      <div class="rtsp-hls-table-container">
        <table class="rtsp-hls-table">
          <thead>
            <tr>
              <th>ID</th>
              <th>流名称</th>
              <th>RTSP 地址</th>
              <!-- <th>HLS 播放地址</th> -->
              <th>状态</th>
              <th>操作</th>
            </tr>
          </thead>
          <tbody>
            <tr v-if="streams.length === 0">
              <td colspan="5" style="text-align: center; padding: 20px">暂无流配置，请添加流</td>
            </tr>
            <tr v-for="(stream, index) in streams" :key="index">
              <td>{{ stream.id }}</td>
              <td>{{ stream.name }}</td>
              <td>{{ stream.rtsp }}</td>
              <!-- <td>
                <span class="rtsp-hls-url">{{ getHlsUrl(stream) }}</span>
              </td> -->
              <td :class="getStatusClass(stream.status)">{{ getStatusText(stream.status) }}</td>
              <td>
                <!-- <button
                  class="rtsp-hls-button btn-sm"
                  :class="{ 'stop-btn': stream.status === 'running' }"
                  @click="toggleStreamStatus(index)"
                >
                  {{ stream.status === 'running' ? '停止' : '启动' }}
                </button> -->

                <button
                  v-if="stream.status !== 'running'"
                  class="rtsp-hls-button btn-sm"
                  :disabled="stream.startBtnText === '启动中 ...'"
                  @click="startStream(stream.id)"
                >
                  {{ stream.startBtnText || '启动' }}
                </button>

                <button
                  v-if="stream.status !== 'stopped'"
                  class="rtsp-hls-button btn-sm stop-btn"
                  :disabled="stream.startBtnText === '停止中 ...'"
                  @click="stopStreaming(stream.id)"
                >
                  {{ stream.stopBtnText || '停止' }}
                </button>

                <button
                  v-if="stream.status !== 'stopped'"
                  class="rtsp-hls-button btn-sm"
                  style="background-color: #28a745; margin-left: 4px"
                  @click="showPreview(stream.hlsUrl)"
                >
                  预览
                </button>
                <button
                  v-if="stream.status !== 'running'"
                  class="rtsp-hls-button delete-btn"
                  @click="deleteStreamConfig(stream.id)"
                >
                  删除
                </button>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>

    <!-- 日志区 -->
    <div class="rtsp-hls-log-area">
      <div style="display: flex; justify-content: space-between; align-items: center">
        <h3>日志</h3>
        <button id="clearLogBtn" class="rtsp-hls-button btn-sm" @click="clearLog">清空</button>
      </div>
      <div id="log" ref="logContainer" class="rtsp-hls-log" v-html="logContent"></div>
    </div>

    <!-- 预览窗口 -->
    <div v-if="previewVisible" class="rtsp-hls-preview-modal" @click.self="closePreview">
      <div class="rtsp-hls-preview-content">
        <div class="rtsp-hls-preview-header">
          <h3>视频预览</h3>
          <button class="rtsp-hls-button" @click="closePreview">关闭</button>
        </div>
        <div class="rtsp-hls-url-container">
          <div class="rtsp-hls-url-label">HLS 播放地址：</div>
          <div class="rtsp-hls-url-display">{{ previewUrl }}</div>
          <button class="rtsp-hls-button" @click="copyUrl">复制地址</button>
        </div>
        <div class="rtsp-hls-video-container">
          <video
            ref="videoRef"
            controls
            :src="previewUrl"
            style="max-width: 100%; max-height: 500px"
            @loadeddata="onVideoLoaded"
            @canplay="onVideoLoaded"
          ></video>
          <!-- @error="onVideoError" -->
          <!-- <div v-if="!videoLoaded" class="rtsp-hls-load-info">视频加载中...</div> -->
          <!-- <div v-if="videoError" class="rtsp-hls-load-error"> -->
          <!-- 视频加载错误，请检查流是否正常运行 -->
          <!-- </div> -->
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick, onBeforeUnmount } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import '../assets/rtsp-hls.css'
import Hls from 'hls.js'
// import HlsPlayer from './HlsPlayer.vue'
// import '../assets/video.min.js'

// 响应式数据
const streamName = ref('')
const rtspUrl = ref('')
const hlsPort = ref('8081')
const streams = ref([])
const logContainer = ref(null)
const logContent = ref('')

const logs = ref([])

const videoEl = ref(null)
let hls = null

// 预览窗口相关
const previewVisible = ref(false)
const previewUrl = ref('')
const videoLoaded = ref(false)
const videoError = ref(false)
const videoRef = ref(null)

// 新流配置表单
const newStream = ref({
  name: '',
  rtsp: 'rtsp://user:pass@ip:port/path',
  port: 8080
})

// 重置新流配置表单
const resetNewStream = () => {
  newStream.value = {
    name: '',
    rtsp: 'rtsp://user:pass@ip:port/path',
    port: 8080
  }
}

// 加载流配置列表
// const loadStreams = () => {
//   // loading.value = true
//   window.api?.loadStreamsConfig()
// }

// 流配置列表处理函数
// const handleStreamsConfigList = (data) => {
//   console.log('Received streams config list:', data)
//   streams.value = data

// }

// 日志处理函数
const handleAppLog = (log) => {
  console.log('Handling log:', log)

  const timestamp = new Date().toLocaleTimeString()
  let colorClass = ''

  // 确保log是字符串类型
  const logString = String(log || '')

  if (logString.includes('[ERROR]')) {
    colorClass = 'rtsp-hls-error-log'
  } else if (logString.includes('[RETRY]')) {
    colorClass = 'rtsp-hls-retry-log'
  } else if (logString.includes('[INFO]')) {
    colorClass = 'rtsp-hls-info-log'
  }

  // 新日志在顶部
  logContent.value = `[${timestamp}] <span class="${colorClass}">${logString}</span><br><br>${logContent.value}`

  // 自动滚动到顶部
  nextTick(() => {
    if (logContainer.value) {
      logContainer.value.scrollTop = 0
    }
  })

  // nextTick(() => {
  //   if (logContainer.value) {
  //     // logContainer.value.scrollTop = logContainer.value.scrollHeight
  //     logContainer.value.scrollTo(0)
  //   }
  // })
}

// IPC事件监听
const setupIpcListeners = () => {
  // 监听流配置列表更新
  window.api?.onStreamsConfigList((event, data) => {
    console.log('Received streams config list:', data)
    streams.value = data
    // loading.value = false
    handleAppLog(`[INFO] 流配置列表已更新，当前共有 ${data.length} 个流配置。`)
  })

  // 监听流配置列表
  // window.api?.onStreamsConfigList(handleStreamsConfigList)

  // 监听应用日志
  window.api?.addLog((event, log) => {
    console.log('Received log:', log)
    logs.value.unshift(log)
    // 只保留最近10条日志
    if (logs.value.length > 10) {
      logs.value = logs.value.slice(0, 10) // 删除多余的日志
    }
  })

  // window.api?.onAppConfig((event, config) => {
  //   appConfig.value = config
  //   console.log('收到应用配置:', config)
  // })

  // 监听日志
  // window.api?.onAppLog(handleAppLog)
}

// const appConfig = ref({ server: { hlsPort: 8080 } })

onMounted(() => {
  setupIpcListeners()

  // 加载流配置
  window.api?.loadStreamsConfig()

  // 获取应用配置
  // window.api?.getAppConfig()

  // 处理 addLog 通道
  // window.api?.addLog((event, log) => {
  //   handleAppLog(log)
  // })
})

onBeforeUnmount(() => {
  // 清理事件监听器
  window.api?.removeAllListeners('streams-config-list')
  window.api?.removeAllListeners('addLog')

  // 停止所有转码服务
  window.api?.stopAllStreaming()

  // 销毁HLS实例
  if (hls) {
    hls.destroy()
    hls = null
  }
})

// 添加流配置
const addStreamConfig = () => {
  if (!newStream.value.id || !newStream.value.name || !newStream.value.rtsp) {
    ElMessage.error('请填写完整的流配置信息')
    return
  }

  // 验证RTSP地址格式
  if (!newStream.value.rtsp.startsWith('rtsp://')) {
    ElMessage.error('RTSP地址必须以rtsp://开头')
    return
  }
  const config = {
    id: newStream.value.id,
    name: newStream.value.name,
    rtsp: newStream.value.rtsp
  }
  window.api?.addStreamConfig(config)

  // adding.value = true
  try {
    // 将响应式对象转换为普通对象，避免IPC序列化问题
    // const config = {
    //   id: newStream.value.id,
    //   name: newStream.value.name,
    //   rtsp: newStream.value.rtsp
    // }
    // window.api?.addStreamConfig(config)
    // window.api?.addStreamConfig(...newStream.value)
    // showAddDialog.value = false
    // resetNewStream()
    // 这里不立即显示成功消息，等待主进程广播更新后再显示
  } catch (error) {
    console.error('添加流配置失败:', error)
    ElMessage.error('添加流配置失败，请检查控制台日志')
  } finally {
    // adding.value = false
  }
}

const runningBtnText = ref('启动转码服务')

// 启动转码服务
const startStream = (id) => {
  // 找到对应流的索引
  const stream = streams.value.find((stream) => stream.id === id)
  // if (!stream) {
  //   ElMessage.error(`未找到ID为${id}的流配置`)
  //   return
  // }
  let msg = `[INFO] 启动转码服务，id： ${id} 。请稍候...`
  msg += `<br> 流名称： ${stream.name}`
  msg += `<br> RTSP地址： ${stream.rtsp}`
  handleAppLog(msg)
  window.api?.startStream(id)
  // runningBtnText.value = '启动中 ...'
}

const startStreamSuccess = (id) => {
  // 找到对应流的索引
  const stream = streams.value.find((stream) => stream.id === id)
  if (!stream) {
    ElMessage.error(`未找到ID为${id}的流配置`)
    return
  }
  let msg = `[INFO] 启动转码服务成功，id： ${id} 。`
  msg += `<br> 流名称： ${stream.name}`
  msg += `<br> RTSP地址： ${stream.rtsp}`
  handleAppLog(msg)
  // runningBtnText.value = '启动转码服务'
}

// 停止所有转码服务
const stopAllStreaming = () => {
  // 显示确认对话框
  ElMessageBox.confirm(
    '确定要重置所有转码服务吗？这将停止所有正在运行的转码并重新加载配置。',
    '确认重置',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  )
    .then(() => {
      try {
        handleAppLog('[INFO] 开始重置所有转码服务...')
        // 1. 停止所有转码
        window.api?.stopAllStreaming()
      } catch (error) {
        console.error('重置所有转码失败:', error)
        handleAppLog(`[ERROR] 重置所有转码失败: ${error.message}`)
        ElMessage.error('重置所有转码失败，请查看日志')
      }
    })
    .catch(() => {
      // 用户取消操作
      ElMessage.info('已取消重置操作')
    })
}

const stopStreaming = (streamId) => {
  // 找到对应流的索引
  const stream = streams.value.find((stream) => stream.id === streamId)
  if (!stream) {
    ElMessage.error(`未找到ID为${streamId}的流配置`)
    return
  }
  let msg = `[INFO] 停止转码服务，id： ${streamId} 。请稍候...`
  msg += `<br> 流名称： ${stream.name}`
  msg += `<br> RTSP地址： ${stream.rtsp}`
  handleAppLog(msg)
  window.api?.stopStreaming(streamId)
}

// 切换流状态
// const toggleStreamStatus = (index) => {
//   let msg = `[INFO] 准备开启转码服务，序号： ${index} 。请稍候...`
//   msg += `<br> 流名称： ${streams.value[index].name}`
//   msg += `<br> RTSP地址： ${streams.value[index].rtsp}`
//   msg += `<br> HLS地址： ${getHlsUrl(streams.value[index])}`
//   msg += `<br> HLS端口： ${streams.value[index].port}`
//   handleAppLog(msg)
//   console.log('streams.value[index]:', streams.value[index])
//   window.api?.toggleStreamStatus(index)
// }

// 删除流配置
const deleteStreamConfig = (id) => {
  if (confirm('确定要删除这个流配置吗？')) {
    window.api?.deleteStreamConfig(id)
  }
}

// 清空日志
const clearLog = () => {
  logContent.value = ''
  window.api?.sendAppLog('[INFO] 日志已清空')
}

// 获取HLS地址
// const getHlsUrl = (stream) => {
//   const port = appConfig.value.server?.hlsPort || 8080
//   const url = `http://localhost:${port}/hls/${stream.id}.m3u8`
//   console.log(`构建HLS URL: ${url}, 流ID: ${stream.id}, 使用端口: ${port}`)
//   return url
// }

// 获取状态类名
const getStatusClass = (status) => {
  switch (status) {
    case 'running':
      return 'rtsp-hls-status-running'
    case 'stopped':
      return 'rtsp-hls-status-stopped'
    case 'retrying':
      return 'rtsp-hls-status-retrying'
    case 'error':
      return 'rtsp-hls-status-error'
    default:
      return ''
  }
}

// 获取状态文本
const getStatusText = (status) => {
  switch (status) {
    case 'running':
      return '运行中'
    case 'stopped':
      return '已停止'
    case 'retrying':
      return '重试中'
    case 'error':
      return '错误'
    default:
      return '未知'
  }
}

// 更新script部分的预览相关函数
// 显示预览
const showPreview = (url) => {
  previewUrl.value = url
  previewVisible.value = true
  videoLoaded.value = false
  videoError.value = false

  // 销毁之前可能存在的hls实例
  if (hls) {
    hls.destroy()
    hls = null
  }

  console.log('Attempting to load HLS stream:', url)

  // 添加一个短暂的延迟以确保DOM已更新
  setTimeout(() => {
    if (videoRef.value) {
      // 先尝试清空并重置视频元素
      videoRef.value.pause()
      videoRef.value.src = ''

      // 检查浏览器是否支持HLS原生播放
      if (videoRef.value.canPlayType('application/vnd.apple.mpegurl')) {
        // 原生支持HLS，直接使用src属性
        console.log('Browser supports HLS natively')
        // try {
        //   videoRef.value.src = url
        //   videoRef.value.load()
        //   // 自动播放（可能需要用户交互才能正常工作）
        //   videoRef.value.play().catch((err) => {
        //     console.log('Auto-play was prevented:', err)
        //     // 用户点击播放按钮时仍能播放
        //   })
        // } catch (error) {
        //   console.error('Error loading video natively:', error)
        //   videoError.value = true
        // }
      } else if (Hls.isSupported()) {
        // 浏览器不支持原生 HLS，但支持 MediaSource Extensions，使用hls.js
        console.log('Browser does not support HLS natively, using hls.js')
        try {
          hls = new Hls()

          // 监听hls.js的事件
          hls.on(Hls.Events.MEDIA_ATTACHED, () => {
            console.log('Media attached successfully')
          })

          //
          hls.on(Hls.Events.MANIFEST_PARSED, (event, data) => {
            console.log('Manifest parsed successfully', data)
            videoLoaded.value = true
            videoError.value = false

            // 尝试自动播放
            videoRef.value.play().catch((err) => {
              console.log('Auto-play was prevented:', err)
            })
          })

          hls.on(Hls.Events.ERROR, (event, data) => {
            console.error('HLS error:', data)
            videoLoaded.value = false
            videoError.value = true

            let errorMessage = 'HLS加载错误'
            if (data.details === 'manifestLoadError') {
              errorMessage = '无法加载播放列表文件，请检查流地址是否正确'
            } else if (data.details === 'mediaError') {
              errorMessage = '媒体数据错误'
            }

            console.error('HLS error details:', errorMessage)
          })

          // 将hls实例附加到video元素并加载流
          hls.attachMedia(videoRef.value)
          hls.loadSource(url)
        } catch (error) {
          console.error('Error initializing HLS:', error)
          videoError.value = true
        }
      } else {
        // 浏览器不支持HLS播放
        console.error('Browser does not support HLS playback')
        videoError.value = true
      }
    }
  }, 100)
}

// 视频加载完成
const onVideoLoaded = () => {
  console.log('Video loaded successfully')
  videoLoaded.value = true
  videoError.value = false
}
// 视频加载错误处理函数增强
const onVideoError = (event) => {
  if (!previewVisible.value) {
    console.log('预览未显示，忽略错误')
    return
  }
  console.error('Video loading error:', event)
  videoLoaded.value = false
  videoError.value = true

  // 尝试获取更详细的错误信息
  if (event.target && event.target.error) {
    const error = event.target.error
    let errorMessage = '未知错误'

    switch (error.code) {
      case error.MEDIA_ERR_ABORTED:
        errorMessage = '视频加载被用户中止'
        break
      case error.MEDIA_ERR_NETWORK:
        errorMessage = '网络错误导致视频加载失败'
        break
      case error.MEDIA_ERR_DECODE:
        errorMessage = '视频解码失败'
        break
      case error.MEDIA_ERR_SRC_NOT_SUPPORTED:
        errorMessage = '视频格式不支持，正在尝试使用HLS.js处理'
        // 如果遇到格式不支持的错误，尝试使用hls.js
        if (previewUrl.value && videoRef.value && Hls.isSupported() && !hls) {
          try {
            hls = new Hls()
            hls.attachMedia(videoRef.value)
            hls.loadSource(previewUrl.value)
          } catch (err) {
            console.error('Failed to initialize HLS.js as fallback:', err)
          }
        }
        break
    }
    console.error('Video error details:', errorMessage)
  }
}

// 关闭预览时清理HLS实例
const closePreview = () => {
  previewVisible.value = false
  videoLoaded.value = false
  videoError.value = false
  if (videoRef.value) {
    console.log('停止视频播放和加载')
    videoRef.value.pause()
    videoRef.value.src = ''
    videoRef.value.load() // 这是关键步骤，确保完全停止所有网络请求
  }
  // 销毁HLS实例
  if (hls) {
    console.log('销毁HLS实例')
    // 移除所有事件监听器
    hls.removeAllListeners()
    hls.off(Hls.Events.ERROR)
    hls.off(Hls.Events.MEDIA_ATTACHED)
    hls.off(Hls.Events.MANIFEST_PARSED)
    hls.stopLoad()
    // 确保所有资源都被释放
    hls.detachMedia()
    hls.destroy()
    hls = null
  }
}

// 视频加载完成
// const onVideoLoaded = () => {
//   videoLoaded.value = true
//   videoError.value = false
// }

// 视频加载错误
// const onVideoError = () => {
//   videoLoaded.value = false
//   videoError.value = true
//   console.error('视频加载错误:', previewUrl.value)
// }

// 关闭预览
// const closePreview = () => {
//   previewVisible.value = false
// }

// 复制地址
const copyUrl = () => {
  navigator.clipboard
    .writeText(previewUrl.value)
    .then(() => {
      alert('地址已复制到剪贴板')
    })
    .catch((err) => {
      console.error('复制失败:', err)
    })
}
</script>
